﻿using BCData.TMS.MarketingCoupon.MarketingCouponStatistics;
using BCDto.TMS.MarketingCoupon.MarketingCouponStatistics;
using System;
using System.Collections.Generic;
using System.Linq;
using BCService.Utils;
using BCCommon;
using BCCommon.TMS.Transport;
using BCEntity.Common.EntityNameConst;
using BCDto.Sim.Admin.Admin;
using BCCommon.Extensions;

namespace BCService.TMS.MarketingCoupon.MarketingCouponStatistics
{
    public class MarketingCouponStatisticsService : IMarketingCouponStatisticsService
    {
        private readonly IMarketingCouponStatisticsData marketingCouponStatisticsData;
        private readonly IRedisService redisService;
        private readonly string key = $"{EntityNameConst.MarketingCouponStatisticsEntity}";
        private readonly string keyDetail = $"{EntityNameConst.MarketingCouponStatisticsDetailEntity}";
        public MarketingCouponStatisticsService(IMarketingCouponStatisticsData marketingCouponStatisticsData,
            IRedisService redisService)
        {
            this.marketingCouponStatisticsData = marketingCouponStatisticsData;
            this.redisService = redisService;
        }

        public MarketingCouponStatisticsDto GetMarketingCouponStatistics(AdminDto admin, bool isCommonBusiness, long? vehicleTransportBusinessConfigId)
        {
            long agentRecordId = admin.AgentRecord.AgentRecordId;
            string cacheKey = this.redisService.GetKey(key, agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var list = this.marketingCouponStatisticsData.GetStatistics(agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId).GetAwaiter().GetResult();
                var result = list.As<MarketingCouponStatisticsDto>();
                if (result.CouponAllCount == 0)
                {
                    result.UsingPercent = "0";
                    result.UnusedPercent = "0";
                    result.ReceivedPercent = "0";
                    result.RemainPercent = "0";
                    result.InvalidPercent = "0";
                }
                else
                {
                    result.UsingPercent= Compare.GetRate(result.UsingAllCount, result.CouponAllCount);
                    result.UnusedPercent = Compare.GetRate(result.UnusedAllCount, result.CouponAllCount);
                    result.ReceivedPercent = Compare.GetRate(result.ReceivedAllCount, result.CouponAllCount);
                    result.RemainPercent = Compare.GetRate(result.RemainAllCount, result.CouponAllCount);
                    result.InvalidPercent = Compare.GetRate(result.InvalidAllCount, result.CouponAllCount);
                }
                if (result.CouponAllAmount == 0)
                {
                    result.UsingAmountPercent = "0";
                    result.UnusedAmountPercent = "0";
                    result.ReceivedAmountPercent = "0";
                    result.RemainAmountPercent = "0";
                    result.InvalidAmountPercent = "0";
                }
                else
                {
                    result.UsingAmountPercent = Compare.GetRate(result.UsingAllAmount, result.CouponAllAmount);
                    result.UnusedAmountPercent = Compare.GetRate(result.UnusedAllAmount, result.CouponAllAmount);
                    result.ReceivedAmountPercent = Compare.GetRate(result.ReceivedAllAmount, result.CouponAllAmount);
                    result.RemainAmountPercent = Compare.GetRate(result.RemainAllAmount, result.CouponAllAmount);
                    result.InvalidAmountPercent = Compare.GetRate(result.InvalidAllAmount, result.CouponAllAmount);
                }
                return result;
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }

        public IEnumerable<MarketingCouponStatisticsDetailDto> GetDetailList(AdminDto admin, bool isCommonBusiness, long? vehicleTransportBusinessConfigId,
             bool? isExpired, DateTime? startDate, DateTime? endDate)
        {
            long agentRecordId = admin.AgentRecord.AgentRecordId;
            string cacheKey = this.redisService.GetKey(keyDetail, agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId, isExpired);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var list = this.marketingCouponStatisticsData.GetDetailList(agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId, isExpired).GetAwaiter().GetResult();
                var result = list.As<IEnumerable<MarketingCouponStatisticsDetailDto>>();
                foreach (var item in result)
                {
                    var receivedCount = marketingCouponStatisticsData.GetReceiveCount(item.MarketingCouponTypeId, startDate, endDate).GetAwaiter().GetResult();
                    item.ReceivedCount = receivedCount;
                    var usingCount = marketingCouponStatisticsData.GetUsingCount(item.MarketingCouponTypeId, startDate, endDate).GetAwaiter().GetResult();
                    item.UsingCount = usingCount;
                }
                return result;
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }

        public PageableList<MarketingCouponStatisticsDetailDto> GetDetailQuery(AdminDto admin, bool isCommonBusiness, long? vehicleTransportBusinessConfigId,
            bool? isExpired, DateTime? startDate, DateTime? endDate, int pageIndex, int pageSize)
        {
            long agentRecordId = admin.AgentRecord.AgentRecordId;
            string cacheKey = this.redisService.GetKey(keyDetail, agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId, isExpired);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var (list, count) = this.marketingCouponStatisticsData.GetDetailQuery(agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId,
                    isExpired, pageIndex, pageSize).GetAwaiter().GetResult();
                var result = list.As<IEnumerable<MarketingCouponStatisticsDetailDto>>();
                foreach (var item in result)
                {
                    var currentReceivedCount = marketingCouponStatisticsData.GetReceiveCount(item.MarketingCouponTypeId, startDate, endDate).GetAwaiter().GetResult();
                    item.CurrentReceivedCount = currentReceivedCount;
                    var currentUsingCount = marketingCouponStatisticsData.GetUsingCount(item.MarketingCouponTypeId, startDate, endDate).GetAwaiter().GetResult();
                    item.CurrentUsingCount = currentUsingCount;
                }
                return new PageableList<MarketingCouponStatisticsDetailDto>()
                {
                    Items = result,
                    Count = count,
                };
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }


        public MarketingCouponStatisticsDto GetMarketingCouponAgentStatistics(AdminDto admin, bool? isCommonBusiness,
            long? vehicleTransportBusinessConfigId, DateTime? startDate, DateTime? endDate)
        {
            long agentRecordId = admin.AgentRecord.AgentRecordId;
            string cacheKey = this.redisService.GetKey(key, agentRecordId, isCommonBusiness,
                vehicleTransportBusinessConfigId,
                startDate, endDate);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var entity = this.marketingCouponStatisticsData.GetMarketingCouponAgentStatistics(agentRecordId,
                    isCommonBusiness,
                    vehicleTransportBusinessConfigId, startDate, endDate).GetAwaiter().GetResult();
                var result = entity.As<MarketingCouponStatisticsDto>();
                if (result.CouponAllCount == 0)
                {
                    result.UsingPercent = "0";
                    result.UnusedPercent = "0";
                    result.ReceivedPercent = "0";
                    result.RemainPercent = "0";
                    result.InvalidPercent = "0";
                }
                else
                {
                    result.UsingPercent = Compare.GetRate(result.UsingAllCount, result.CouponAllCount);
                    result.UnusedPercent = Compare.GetRate(result.UnusedAllCount, result.CouponAllCount);
                    result.ReceivedPercent = Compare.GetRate(result.ReceivedAllCount, result.CouponAllCount);
                    result.RemainPercent = Compare.GetRate(result.RemainAllCount, result.CouponAllCount);
                    result.InvalidPercent = Compare.GetRate(result.InvalidAllCount, result.CouponAllCount);
                }

                if (result.CouponAllAmount == 0)
                {
                    result.UsingAmountPercent = "0";
                    result.UnusedAmountPercent = "0";
                    result.ReceivedAmountPercent = "0";
                    result.RemainAmountPercent = "0";
                    result.InvalidAmountPercent = "0";
                }
                else
                {
                    result.UsingAmountPercent = Compare.GetRate(result.UsingAllAmount, result.CouponAllAmount);
                    result.UnusedAmountPercent = Compare.GetRate(result.UnusedAllAmount, result.CouponAllAmount);
                    result.ReceivedAmountPercent = Compare.GetRate(result.ReceivedAllAmount, result.CouponAllAmount);
                    result.RemainAmountPercent = Compare.GetRate(result.RemainAllAmount, result.CouponAllAmount);
                    result.InvalidAmountPercent = Compare.GetRate(result.InvalidAllAmount, result.CouponAllAmount);
                }

                var transportBusinessString = string.Empty;
                var amountList = this.marketingCouponStatisticsData.GetMarketingCouponTransportBusinessAmount(
                    agentRecordId, isCommonBusiness, vehicleTransportBusinessConfigId,
                    startDate, endDate).Result.ToList();
                for (int i = 0; i < amountList.Count; i++)
                {
                    if (amountList[i].IsCommonBusiness)
                    {
                        transportBusinessString += amountList[i].TransportBusiness+ amountList[i].MarketingCouponAmount + "元";
                    }
                    else
                    {
                        transportBusinessString += ((TransportBusinessType)Enum.Parse(typeof(TransportBusinessType), amountList[i].TransportBusiness)).GetDescriptionString() + amountList[i].MarketingCouponAmount + "元";
                    }

                    if (i < amountList.Count - 1)
                    {
                        transportBusinessString += " ";
                    }
                }
                result.TransportBusinessString = transportBusinessString;
                return result;
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }


    }
}
